home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / alloc_v2 / sysmem.c < prev   
C/C++ Source or Header  |  1987-06-16  |  6KB  |  183 lines

  1. /*****************************************************************************
  2. (c) Copyright 1984,1985,1986,1987, Front Line Software. All Rights Reserved.
  3.  
  4.                   SYS_MEM.C
  5.  
  6.                  Release 2.0
  7.  
  8.     Written :        12/23/84    Initial Release
  9.     Updated :        07/16/87    Added more documenation and DOSALLOC.OBJ
  10.  
  11.     By:         Front Line Software Co.
  12.             P.O. Box 217
  13.             Lowell, Mass   01853
  14.  
  15.     If you find these functions useful please contribute a small donation
  16.     ( $5.00 ) to help offset the development time. Donations may be sent to
  17.     the above address.
  18.  
  19.     If you can't afford the donation we would still like to get some
  20.     feedback on the number of people that find this useful and/or comments
  21.     on the package. Shareware can be a good deal for both the developers
  22.     and the users, but only if it is supported. We can do alot more
  23.     with shareware packages if it is shown to be worth our time. Let
  24.     us know what you think!
  25.  
  26.     These functions will allow Mark Williams 'C' large model compiler
  27.     (and any other 'C' compiler runnning under MS-DOS Operating System)
  28.     to ALLOC() and FREE() ALL available system memory.
  29.  
  30.     Currently, Mark Williams will only allow a user to ALLOC 64K of
  31.     memory with the Large Model. The user is paying a penalty for using
  32.     the large model (slow pointer arithmetic, slower function calls
  33.     due to pushing the two values on the stack, and less available
  34.     data space due to the double value pointers).
  35.  
  36.     There is no reason why the user should not get the full benefit of
  37.     access to ALL of the memory available in the system. These routines
  38.     allow the user to get the extra memory!
  39.  
  40.     To adapt to another compiler the only routine which will have to be
  41.     changed is the DOSALLOC.ASM routine. The 'entry' and 'exit' code
  42.     which preserves the registers needed by the compiler will have to
  43.     be updated. Check your compiler manual for how to interface to
  44.     assembly language routines. Don't be afraid to try it, it is really
  45.     quite simple.
  46.  
  47.     The SALLOC() and SFREE() functions are used with the exact
  48.     same parameters as ALLOC and FREE as defined in K & R. These are
  49.     the only two points your 'C' program should call. SALLOC will give
  50.     you a pointer to the memory you have asked for, and SFREE will
  51.     place that memory back into the pool.
  52.  
  53.     Compile SYS_MEM.C and link both SYS_MEM.OBJ and DOSALLOC.OBJ with your
  54.     program. Thats it!
  55.  
  56.     We have added DOSALLOC.OBJ to the files as it was pointed out many users
  57.     don't have assemblers.
  58.  
  59. ******************************************************************************/
  60.  
  61. #include <stdio.h>
  62.  
  63. typedef int ALIGN;    /* force alignment on IBM PC */
  64.  
  65. union header {          /* sfree block header */
  66.     struct   {
  67.         union header *ptr;      /* to next sfree block */
  68.         unsigned int size;      /* size of this sfree block */
  69.              } s;
  70.     ALIGN      x;               /* force alignment */
  71.     };
  72.  
  73. typedef union header HEADER;
  74. /*****************************************************************************/
  75.  
  76.  
  77.  
  78. /*****************************************************************************/
  79. static HEADER base;             /* empty list to get started */
  80. static HEADER *sallocp = NULL;  /* last allocated block */
  81.  
  82. char *salloc(nbytes)            /* general-purpose storage allocator */
  83. unsigned nbytes;
  84. {
  85. HEADER *morecore();
  86. HEADER *p,*q;
  87. int nunits;
  88.  
  89.  
  90.     if ( nbytes > ( 65535 - sizeof(HEADER) ) )
  91.         return(NULL);
  92.     nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
  93.     if ((q = sallocp) == NULL)            /* no sfree list yet */
  94.         {
  95.         base.s.ptr = sallocp = q = &base;
  96.         base.s.size = 0;
  97.         }
  98.     for (p=q->s.ptr;; q=p, p=p->s.ptr)
  99.         {
  100.         if ((long)p->s.size >= (long)nunits)      /* big enough */
  101.             {
  102.             if ((long)p->s.size == (long)nunits)  /* exactly */
  103.                 q->s.ptr = p->s.ptr;
  104.             else
  105.                 {                           /* allocate tail end */
  106.                 p->s.size -= nunits;
  107.                 p += p->s.size;
  108.                 p->s.size = nunits;
  109.                 }
  110.             sallocp = q;
  111.             return((char *) (p+1));
  112.             }
  113.         if ((long)p == (long)sallocp)       /* wrapped around sfree list */
  114.             if (( p = morecore(nunits)) == NULL)
  115.                 return(NULL);               /* none left */
  116.        }
  117. }
  118. /*****************************************************************************/
  119.  
  120.  
  121.  
  122. /*****************************************************************************/
  123. #define NSALLOC     2700        /* size of block to get from DOS */
  124.                                 /* ( NSALLOC X 6 ( 6 is the size of HEADER )
  125.                                     = SIZE OF BLOCK REQUESTED ) */
  126.  
  127. static HEADER *morecore(nu)                 /* asks system(DOS) for memory */
  128. unsigned nu;
  129. {
  130. char *dosalloc();
  131. char *cp;
  132. HEADER *up;
  133. int rnu;
  134.  
  135.     rnu = NSALLOC * ((nu+NSALLOC-1) / NSALLOC);
  136.     cp = dosalloc((unsigned)rnu * sizeof(HEADER));
  137.     if ( (long)cp == NULL )            /* no space available */
  138.         return(NULL);
  139.     up = (HEADER *)cp;
  140.     up->s.size = rnu;
  141.     sfree((char *) (up + 1));
  142.     return(sallocp);
  143. }
  144. /*****************************************************************************/
  145.  
  146.  
  147.  
  148. /*****************************************************************************/
  149. sfree(ap)            /* put block ap in sfree list */
  150. char *ap;
  151. {
  152. HEADER *p, *q;
  153.  
  154. int h,i,j;
  155. h = i = j = 0;
  156.  
  157.     p = (HEADER *)ap - 1;                   /* point to header */
  158.     for (q=sallocp;!((long)p>(long)q && (long)p<(long)q->s.ptr);q=q->s.ptr)
  159.         {
  160.         if ((h=((long)q >= (long)q->s.ptr)) &&
  161.              (((i=((long)p > (long)q)) ||
  162.              (j = ((long)p < (long)q->s.ptr)))))
  163.             break;                          /* at one end or the other */
  164.         }
  165.  
  166.     if ((long)p+p->s.size == (long)q->s.ptr)/* join to upper nbr */
  167.         {
  168.         p->s.size += q->s.ptr->s.size;
  169.         p->s.ptr = q->s.ptr->s.ptr;
  170.         }
  171.     else
  172.         p->s.ptr = q->s.ptr;
  173.     if ((long)q+q->s.size == (long)p)      /* join lower nbr */
  174.         {
  175.         q->s.size += p->s.size;
  176.         q->s.ptr = p->s.ptr;
  177.         }
  178.     else
  179.         q->s.ptr = p;
  180.     sallocp = q;
  181. }
  182. /*****************************************************************************/
  183.